<template>
  <div style="padding: 5px; border: 1px solid #ccc!important;">
    <async-comp v-if="reload"></async-comp>
  </div>
</template>

<script>
  
  import {
    defineComponent,
    defineAsyncComponent,
    ref,
    reactive,
    watch,
    watchEffect,
    computed,
    shallowReactive,
    shallowReadonly,
    shallowRef,
    readonly,
    toRaw,
    isRef,
    isProxy,
    isReactive,
    isReadonly,
    toRef,
    toRefs,
    nextTick
  } from 'vue'

  // 使用 eval编译js代码
  const mysetup = `
    (function setup () {
      {{code}}
    })
  `

  // 用一下才行，否则不给打包
  const __a1 = ref()
  const __a2 = reactive({})
  watch (__a1, () =>{})
  watchEffect (() =>{})
  const __a14 = computed(() => {})
  const __a3 = shallowReactive(__a2)
  const __a4 = shallowReadonly(__a2)
  const __a5 = shallowRef(__a2)
  const __a6 = readonly(__a2)
  const __a7 = toRaw(__a2)
  const __a8 = isRef(__a1)
  const __a9 = isProxy(__a2)
  const __a10 = isReactive(__a2)
  const __a11 = isReadonly(__a2)
  const __a12 = toRef(__a2)
  const __a13 = toRefs(__a2)

  // const canRun = ref(false)
  const _code = reactive({})
  // let maxCount = 5

  // 使用 defineAsyncComponent 让代码运行起来
  const AsyncComp = defineAsyncComponent(
    () => new Promise((resolve, reject) => {
      setTimeout(() => {
        const _comp = {
          template: window.__codeTemplate, // _code.template?? '没有得到模板', // 设置模板
          style: [], // 大概是样式设置，但是好像没啥效果
          setup(_props, _ctx) {
            const tmpJs = _code.js // 获取js代码
            let fun = null // 转换后的函数
            try {
              if (tmpJs)
                fun = eval(mysetup.replace('{{code}}', tmpJs)) // 用 eval 把 字符串 变成 函数
            } catch (error) {
              console.error('转换出现异常：', error)
            }

            const re = typeof fun === 'function' ? fun : () => {}

            return {
              ...re(_props, _ctx) // 运行函数，解构返回对象
            }
          }
        }
        resolve(_comp)
      }, 300)
      
    })
  )

  export default defineComponent({
    name: 'el-doc-runcode',
    inheritAttrs: false,
    components: {
      AsyncComp
    },
    props: {
      code: {
        type: Object,
        default: () => {
          return {
            id: 1,
            js: '',
            template: '',
            style: ''
          }
        }
      }
    },
    setup (props, context) {

      const reload = ref(false)

        setTimeout(() => {
          reload.value = true
        }, 300)

      console.log('props', props)
      _code.js = props.code.js
      _code.template = props.code.template
      window.__codeTemplate = _code.template
      _code.style = props.code.style

      return {
        reload
      }

    }
  })
  

</script>